/*
 *  Author: zhaijl 
 *  Url: http://218.1.73.212/down.php
 *  Country: China
 *  
 * ====================================================================
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 * ====================================================================
 *
 * This software based apache mina 2.0 and spring 3.0
 *
 */
package org.cloudy.http.codec;

import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;

import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.write.WriteRequest;

public class Writer implements WriteRequest {
    private static final WriteFuture UNUSED_FUTURE = new WriteFuture () {
        public boolean isWritten () {
            return false;
        }

        public void setWritten () {}

        public IoSession getSession () {
            return null ;
        }

        public void join () {}

        public boolean join ( long timeoutInMillis ) {
            return true ;
        }

        public boolean isDone () {
            return true ;
        }

        public WriteFuture addListener ( IoFutureListener<?> listener ) {
            throw new IllegalStateException ( "You can't add a listener to a dummy future." ) ;
        }

        public WriteFuture removeListener ( IoFutureListener<?> listener ) {
            throw new IllegalStateException ( "You can't add a listener to a dummy future." ) ;
        }

        public WriteFuture await () throws InterruptedException {
            return this;
        }

        public boolean await ( long timeout, TimeUnit unit )
                throws InterruptedException {
            return true;
        }

        public boolean await ( long timeoutMillis ) throws InterruptedException {
            return true ;
        }

        public WriteFuture awaitUninterruptibly () {
            return this;
        }

        public boolean awaitUninterruptibly ( long timeout, TimeUnit unit ) {
            return true;
        }

        public boolean awaitUninterruptibly ( long timeoutMillis ) {
            return true;
        }

        public Throwable getException () {
            return null ;
        }

        public void setException ( Throwable cause ) {}
    };
    
    private final Object message ;
    private final WriteFuture future ;
    private final SocketAddress destination ;

    public Writer ( Object message ) {
        this ( message, null, null ) ;
    }

    public Writer ( Object message, WriteFuture future ) {
        this ( message, future, null ) ;
    }

    public Writer ( Object message, WriteFuture future, SocketAddress destination ) {
        if ( message == null ) throw new NullPointerException ( "message" ) ;
        if ( future == null ) future = UNUSED_FUTURE ;

        this.message = message ;
        this.future = future ;
        this.destination = destination ;
    }

    public WriteFuture getFuture () {
        return future;
    }

    public Object getMessage () {
        return message;
    }

    public WriteRequest getOriginalRequest () {
        return this;
    }

    public SocketAddress getDestination () {
        return destination;
    }

    @Override
    public String toString () {
        if ( getDestination () == null) {
            return message.toString () ;
        }
        
        return message.toString () + " => " + getDestination () ;
    }
}